﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TestOnlineProject.Models.BusinessLogic;
using TestOnlineProject.Models.Entities;
using PagedList;

namespace TestOnlineProject.Areas.Admin.Controllers
{
    [Authorize]
    public class SectionController : Controller
    {
        SectionBLO sectionBLO = new SectionBLO();
        SubjectBLO subjectBLO = new SubjectBLO();
        UserBLO userBLO = new UserBLO();
        ParticipantBLO participantBLO = new ParticipantBLO();

        //
        // GET: /Admin/Section/

        public ActionResult Index(int? page, string keyWord = "", string createdBy = "", int actualUser = 0, int subjectId = 0, string column = "", string sort = "")
        {
            try
            {
                var user = userBLO.Find(int.Parse(HttpContext.User.Identity.Name));
                // Check valid user
                if (user == null)
                {
                    return RedirectToAction("Error", "Account");
                }
                if (!user.IsActivated)
                {
                    return RedirectToAction("Error", "Account");
                }
                var subject = subjectBLO.Find(subjectId);

                // Authorize
                if (subject == null)
                {
                    return HttpNotFound();
                }
                if (!HttpContext.User.IsInRole("1"))
                {
                    if (!participantBLO.CheckParticipant(int.Parse(HttpContext.User.Identity.Name), subjectId))
                    {
                        TempData["Msg"] = "You can not access this subject. Please contact Admin to more details.";
                        return RedirectToAction("Index", "Subject");
                    }
                }

                // No. list.
                var noList = new List<NoModel>();

                List<Section> sections = sectionBLO.ToList(ref noList, page, keyWord, createdBy, actualUser, subjectId, column, sort);

                // Sort states.
                ViewBag.Msg = TempData["Msg"] as string;
                ViewBag.Page = page;
                ViewBag.KeyWord = keyWord;
                ViewBag.SubjectId = subjectId;
                ViewBag.Column = column;
                ViewBag.Sort = sort;
                ViewBag.Subject = subjectBLO.Find(subjectId);
                ViewBag.NoList = noList;

                var createdBys = new List<CreatedByModel>() { 
                    new CreatedByModel() { Value = "mine", Text = "Mine" },
                    new CreatedByModel() { Value = "admin", Text = "Admin" },
                    new CreatedByModel() { Value = "teachers", Text = "Teachers" },
                    new CreatedByModel() { Value = "students", Text = "Students" },
                    new CreatedByModel() { Value = "actualUser", Text = "Actual People" }                
                };
                ViewBag.CreatedByList = new SelectList(createdBys, "Value", "Text");

                // Return.
                var pageNumber = page ?? 1;
                var onePageOfSections = sections.ToPagedList(pageNumber, 10);
                ViewBag.onePageOfSections = onePageOfSections;
                return Request.IsAjaxRequest()
                    ? (ActionResult)PartialView("_List")
                    : View();
            }
            catch (Exception)
            {
                // Wrtite to log file.
                return RedirectToAction("Index", "Error", new { Area = "" });
            }
        }

        public JsonResult AutocompleteUser(string term)
        {
            try
            {
                var users = userBLO.ToList();
                var result = users.Where(u => (u.FullName.ToLower().Contains(term.ToLower()))
                    || (u.Username.ToLower().Contains(term.ToLower()))).Select(u => new { id = u.UserId, value = u.FullName + " - " + u.Username });
                return Json(result, JsonRequestBehavior.AllowGet);
            }
            catch (Exception)
            {
                // Wrtite to log file.
                return null;
            }
        }

        public ActionResult Details(int id = 0)
        {
            try
            {
                var user = userBLO.Find(int.Parse(HttpContext.User.Identity.Name));
                // Check valid user
                if (user == null)
                {
                    return RedirectToAction("Error", "Account");
                }
                if (!user.IsActivated)
                {
                    return RedirectToAction("Error", "Account");
                }
                var section = sectionBLO.Find(id);

                // Authorize
                if (section == null)
                {
                    return HttpNotFound();
                }
                if (!HttpContext.User.IsInRole("1"))
                {
                    if(!section.IsActivated)
                    {
                        TempData["Msg"] = "You can not access this section. Please contact Admin to more details.";
                        return RedirectToAction("Index", new {subjectId = section.SubjectId});
                    }
                    if (!participantBLO.CheckParticipant(int.Parse(HttpContext.User.Identity.Name), section.SubjectId))
                    {
                        TempData["Msg"] = "You can not access this subject. Please contact Admin to more details.";
                        return RedirectToAction("Index", "Subject");
                    }
                }

                ViewBag.Msg = TempData["Msg"] as string;
                ViewBag.Subject = subjectBLO.Find(section.SubjectId);
                return View(section);
            }
            catch (Exception)
            {
                // Wrtite to log file.
                return RedirectToAction("Index", "Error");
            }
        }

        public ActionResult Create(int subjectId)
        {
            try
            {
                var user = userBLO.Find(int.Parse(HttpContext.User.Identity.Name));
                // Check valid user
                if (user == null)
                {
                    return RedirectToAction("Error", "Account");
                }
                if (!user.IsActivated)
                {
                    return RedirectToAction("Error", "Account");
                }

                var subject = subjectBLO.Find(subjectId);

                // Authorize.
                if (subject == null)
                {
                    return HttpNotFound();
                }
                if (!HttpContext.User.IsInRole("1"))
                {
                    if (!participantBLO.CheckParticipant(int.Parse(HttpContext.User.Identity.Name), subjectId))
                    {
                        TempData["Msg"] = "You can not access this subject. Please contact Admin to more details.";
                        return RedirectToAction("Index", "Subject");
                    }
                }

                var section = new Section()
                {
                    SubjectId = subjectId,
                    UserId = int.Parse(HttpContext.User.Identity.Name)
                };
                ViewBag.Subject = subject;
                return View(section);
            }
            catch (Exception)
            {
                // Wrtite to log file.
                return RedirectToAction("Index", "Error");
            }
        }

        [HttpPost]
        public ActionResult Create(Section section)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    int result = sectionBLO.Add(section);
                    if (result > 0)
                    {
                        TempData["Msg"] = "New section has been created.";
                        return RedirectToAction("Details", new { id = section.SectionId });
                    }
                    else
                    {
                        ModelState.AddModelError("", "An error occurred.");
                    }
                }
                ViewBag.Subject = subjectBLO.Find(section.SubjectId);
                return View(section);
            }
            catch (Exception)
            {
                // Wrtite to log file.
                return RedirectToAction("Index", "Error");
            }
        }

        public ActionResult Edit(int id)
        {
            try
            {
                var user = userBLO.Find(int.Parse(HttpContext.User.Identity.Name));
                // Check valid user
                if (user == null)
                {
                    return RedirectToAction("Error", "Account");
                }
                if (!user.IsActivated)
                {
                    return RedirectToAction("Error", "Account");
                }

                var section = sectionBLO.Find(id);

                // Authorize.
                if (section == null)
                {
                    return HttpNotFound();
                }
                
                if (!HttpContext.User.IsInRole("1"))
                {
                    // check valid section
                    if (!section.IsActivated)
                    {
                        TempData["Msg"] = "You can not access this section. Please contact Admin to more details.";
                        return RedirectToAction("Index", new { subjectId = section.SubjectId });
                    }
                    if (section.UserId != int.Parse(HttpContext.User.Identity.Name))
                    {
                        TempData["Msg"] = "You can not access this section. Please contact Admin to more details.";
                        return RedirectToAction("Index", new { subjectId = section.SubjectId });
                    }
                    if (!participantBLO.CheckParticipant(int.Parse(HttpContext.User.Identity.Name), section.SubjectId))
                    {
                        TempData["Msg"] = "You can not access this subject. Please contact Admin to more details.";
                        return RedirectToAction("Index", "Subject");
                    }
                }

                ViewBag.Subject = subjectBLO.Find(section.SubjectId);
                return View(section);
            }
            catch (Exception)
            {
                // Wrtite to log file.
                return RedirectToAction("Index", "Error");
            }
        }

        [HttpPost]
        public ActionResult Edit(Section section)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    int result = sectionBLO.Modify(section);
                    if (result > 0)
                    {
                        TempData["Msg"] = "The section has been updated.";
                        return RedirectToAction("Details", new { id = section.SectionId });
                    }
                    if (result == -1)
                    {
                        TempData["Msg"] = "The section data is out of date. Update unsuccessful.";
                        return RedirectToAction("Details", new { id = section.SectionId });
                    }
                    else
                    {
                        ModelState.AddModelError("", "An error occurred.");
                    }
                }
                ViewBag.Subject = subjectBLO.Find(section.SubjectId);
                return View(section);
            }
            catch (Exception)
            {
                // Wrtite to log file.
                return RedirectToAction("Index", "Error");
            }
        }

        public string Deactivate(string ids = "")
        {
            try
            {
                int result = sectionBLO.Deactivate(ids);
                if (result > 0)
                {
                    return result + " section(s) has been deactivated.";
                }
                else
                {
                    return "Section(s) has been deactivated.";
                }
            }
            catch (Exception)
            {
                // Write to log file.
                return "An error occurred.";
            }
        }

        //
        // GET: /Admin/Question/Activate/5

        public string Activate(string ids = "")
        {
            try
            {
                int result = sectionBLO.Activate(ids);
                if (result > 0)
                {
                    return result + " section(s) has been activated.";
                }
                else
                {
                    return "Section(s) has been activated.";
                }
            }
            catch (Exception)
            {
                // Write to log file.
                return "An error occurred.";
            }
        }

        public string Delete(string ids = "")
        {
            try
            {
                int result = sectionBLO.Remove(ids);
                if (result > 0)
                {
                    return result + " section(s) has been deleted.";
                }
                else
                {
                    return "An error occurred.";
                }
            }
            catch (Exception)
            {
                // Write to log file.
                return "An error occurred.";
            }
        }

        public string AddQuestions(int sectionId, string ids = "")
        {
            try
            {
                int result = sectionBLO.AddQuestions(sectionId, ids);
                if (result > 0)
                {
                    return result + " question(s) has been added.";
                }
                else
                {
                    return "question(s) is already in this section.";
                }
            }
            catch (Exception)
            {
                // Write to log file.
                return "An error occurred.";
            }
        }

        public string RemoveQuestions(int sectionId, string ids = "")
        {
            try
            {
                int result = sectionBLO.RemoveQuestions(sectionId, ids);
                if (result > 0)
                {
                    return result + " question(s) has been removed.";
                }
                else
                {
                    return "question(s) is not in this section.";
                }
            }
            catch (Exception)
            {
                // Write to log file.
                return "An error occurred.";
            }
        }
    }
}
